class Snake {

  // 蛇的容器
  element: HTMLElement;
  // 蛇头
  head: HTMLElement;
  // 蛇身
  bodies: HTMLCollection;

  constructor() {
    this.element = document.getElementById('snake') as HTMLElement;
    this.head = document.querySelector('#snake > div') as HTMLElement;
    this.bodies = this.element.getElementsByTagName('div');
  }

  // 获取蛇头的坐标
  get X() {
    return this.head.offsetLeft;
  }

  get Y() {
    return this.head.offsetTop;
  }

  // 设置蛇的坐标
  set X(value) {
    // 判断设置的值是否与原先的值相同
    if (this.X === value) return;
    // 向上运动时不可反向移动
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
      if (value > this.X) { // 向左走
        value = this.X - 10;
      } else {
        value = this.X + 10;
      }
    }
    // 判断是否撞墙
    if (value > 290 || value < 0) {
      throw new Error('撞墙了,游戏结束')
    }

    // 移动身体
    this.moveBody()
    this.head.style.left = value + 'px';
    this.checkSelf()
  }

  set Y(value) {
    // 判断设置的值是否与原先的值相同
    if (this.Y === value) return;
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
      if (value > this.Y) { // 向左走
        value = this.Y - 10;
      } else {
        value = this.Y + 10;
      }
    }
    // 判断是否撞墙
    if (value > 290 || value < 0) {
      throw new Error('撞墙了,游戏结束')
    }

    // 移动身体
    this.moveBody()
    this.head.style.top = value + 'px';
    this.checkSelf()
  }

  // 增加蛇身
  addBody() {
    this.element.insertAdjacentHTML('beforeend', "<div></div>");
  }

  // 蛇身移动
  moveBody() {
    for (let i = this.bodies.length - 1; i > 0; i--) {
      let X = ((this.bodies[i - 1] as HTMLElement).offsetLeft);
      let Y = ((this.bodies[i - 1] as HTMLElement).offsetTop);

      (this.bodies[i] as HTMLElement).style.left = X + 'px';
      (this.bodies[i] as HTMLElement).style.top = Y + 'px';
    }
  }

  // 检查是否碰到自己的身体
  checkSelf() {
    for (let i = 1; i < this.bodies.length; i++) {
      let X = (this.bodies[i] as HTMLElement).offsetLeft;
      let Y = (this.bodies[i] as HTMLElement).offsetTop;

      if (this.X === X && this.Y === Y) {
        throw new Error('撞到自己,游戏结束')
      }
    }
  }

}



export default Snake;